<?php
/**
 * 唯一ID生成器，提供两种唯一id生成方式
 * 1、使用MC加mysql生成数字型唯一id
 * 2、使用算法产生一个字符串型的唯一id
 * 
 * @author Leo
 * @since 2012.3.23
 */
class Counter_Builder
{    
    /**
     * cache namaspace
     */
    const CACHE_NS = '_counter';
    
    /**
     * 表名称
     */
    const TABLE_COUNTER_NAME = 'counter';

	/**
	 * 单例对象
	 */
	public static $singletonObjects = null;
    
    /**
     * @var Helper_Cache_Memcached
     */
    protected $_cacheInstance;
    
    /**
	 * 获取单例
     * 
	 * @return Counter_Builder
	 * @throws AppException
	 */
	public static function getInstance()
	{
		$className = __CLASS__;
		if( self::$singletonObjects == null )
		{
			self::$singletonObjects = new self;
		}

		return self::$singletonObjects;
	}

	/**
	 * 构造器
	 */
	protected function __construct()
	{
        $this->_cacheInstance = $this->_getCache();
	}

    /**
     * 获取cache实例
     * @return Helper_Cache_Memcached
     */
    protected function _getCache()
    {
        return Common::getCache();
    }
    
    /**
     * 初始化指定key在MC中的值
     * @param string $key 
     */
    public function init( $key )
    {
        $cacheKey = $key . self::CACHE_NS;
        
        //尝试3次获取
        for( $i = 0; $i < 3; $i++ )
        {
            $currentValue = $this->_cacheInstance->get( $cacheKey );
            if( $currentValue !== false )
            {
                break;
            }
        }
        
        //3次仍未获取到，则尝试在数据库中读取
        if( $currentValue === false )
        {
            $dbInstance = Common::getMysql( 'common' );
            $value = $dbInstance->get( self::TABLE_COUNTER_NAME , array( 'key' => $key ) );
            
            if( $value === false )
            {
                if( $dbInstance->add( self::TABLE_COUNTER_NAME , array( 'key' => $key , 'value' => $_SERVER['REQUEST_TIME'] ) ) )
                {
                    $this->_cacheInstance->set( $cacheKey , $_SERVER['REQUEST_TIME'] );
                }
                else
                {
                    throw new AppException( 1000 );
                }
            }
            else
            {
                $this->_cacheInstance->set( $cacheKey , $value['value'] + 10 );
            }
        }
    }
    
    /**
     * 根据key返回唯一的id
     * @param string $key 
     * @return int
     */
    public function getUniqueIdByKey( $key )
    {
        $this->init( $key );
        $value = $this->_cacheInstance->increment( $key . self::CACHE_NS , 1 );
        
        if( $value % 10 === 0 )
        {
            Common::getMysql( 'common' )->update( self::TABLE_COUNTER_NAME , array( 'key' => $key ) , array( 'value' => $value ) );
        }
        
        return $value;
    }
    
    /**
     * 算发生成唯一字符串id
     * @return string
     */
    public static function getUniqueIdByFun()
    {
        $charid = strtoupper( md5( uniqid( mt_rand() , true ) ) );
        $hyphen = chr( 45 );
        return chr( 123 ) . substr( $charid , 0 , 8 ) . $hyphen . substr( $charid , 8 , 4 ) . $hyphen . substr( $charid , 12 , 4 ) . $hyphen . substr( $charid ,16 , 4 ) . $hyphen . substr( $charid , 20 , 12 ) . chr( 125 );
    }
}
?>
